const app         = require('koa')(),
      Router      = require('koa-router'),
      UserService = require('./_UserService');

const router = new Router();

router.get('/', function *(next) {
    this.body = 'Hello World!';
});

// 别名
// Syntax: (name, path, cb*())
router.get('user', '/users/:id', function *(next) {
    console.log(this.url);
    this.body = '';
});

// 多个中间件
// Syntax: (path, middleware1, middleware2, .., cb*())
router.get('/stu/:id',
    function *(next) {
        this.user = yield UserService.findOne(this.params.id);
        yield next;
    }, function *(next) {
        this.name = 'Student';
        yield next;
    }, function *(next) {
        console.log(this.user);
        console.log(this.name);
        this.body = this.user;
    }
);

// 嵌套路由器
// Syntax: parentRouter.use(baseUrl, child.routes(), child.allowedMethods())
const sysRouter     = new Router(),
      sysUserRouter = new Router();

sysUserRouter.get('/', function *(next) {
    // 路由匹配相同时, 会被父级 Route 覆盖
    this.body = 'SysUser root route';
});
sysUserRouter.get('/users', function *(next) {
    this.body = `users: ${this.url}`;
});
sysUserRouter.get('/users/:id(\\d+)', function *(next) {
    this.body = `user: ${this.url}`;
});
sysRouter.get('/sys', function *() {
    // 路由匹配相同时, 覆盖子级 Route
    this.body = 'Sys root route';
});
sysRouter.use('/sys', sysUserRouter.routes(), sysUserRouter.allowedMethods());

// URL参数
// path中可匹配正则表达式, 具体参考: https://github.com/pillarjs/path-to-regexp
router.get('/:category(\\d+)/:title', function *(next) {
    console.log(this.params); // 获取 path 中参数
    // => {category: 'xx', title: 'xx'}
});

// 路由前缀
const menu1Router = new Router(),
      menu2Router = new Router({
          prefix: '/menu2/:id(\\d+)'
      });
menu1Router.prefix('/menu1/:id(\\d+)');

menu1Router.get('/', function *() {
    console.log(this.params);
    this.body = `${this.url}`;
});

menu2Router.get('/', function *() {
    this.body = `${this.url}`;
});

// 获取所有配置的路由
router.routes();

// 在执行 router 的 cb 之前先执行指定的 middleware
// Syntax: router.use([path,] middleware1, middleware12, ..);
router.use(function *(next) {
    console.log('middleware1');
    yield next;
}, function *(next) {
    console.log('middleware2');
    yield next;
});

// router.allowedMethods([opt])

// 路由跳转 router.redirect
// Syntax: router.redirect(source, destination, code)
router.redirect('/redirect', '/users/1'); // 匹配到 redirect 路由后跳转到 '/users/:id' 路由

// 获取指定路由
// Syntax: router.route(name)
// console.log(router.route('user'));

// 根据路由名称和给定的参数生成 url
// Syntax: router.url(name, params)
console.log(router.url('user', {id: 1}));

// router.param
// 处理 path 中的参数
const productRouter = new Router({
    prefix: '/products'
});
productRouter
    .param('id', function *(id, next) {
        console.log(id);
        this.product = {name: 'iphone', price: '5688'};
        yield next;
    })
    .get('/:id(\\d+)', function *() {
        console.log(this.product);
        this.body = '';
    })
    .get('/:id(\\d+)/update', function *() {
        console.log(this.product);
        this.body = '';
    });

// Router.url 根据参数生成 url
console.log(Router.url('/users/:id', {id: 1}));


app
    .use(router.routes())
    .use(sysRouter.routes())
    .use(menu1Router.routes())
    .use(menu2Router.routes())
    .use(productRouter.routes())
    .use(router.allowedMethods())
    .use(sysRouter.allowedMethods());

app.listen(3000);